package com.bestom.waterquality.logic;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;

import com.bestom.waterquality.R;
import com.bestom.waterquality.WaterQualityApplication;
import com.bestom.waterquality.control.DevManageGuider;
import com.bestom.waterquality.control.SDKGuider;
import com.bestom.waterquality.entity.Constant;
import com.bestom.waterquality.util.SharedPreferencesUtil;
import com.bestom.waterquality.util.ToastUtil;
import com.hcnetsdk.jna.ErrorCode;
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO_V20;
import com.hikvision.netsdk.NET_DVR_TIME;
import com.hikvision.netsdk.NET_DVR_VOD_PARA;
import java.util.Calendar;
import java.util.Date;

/**
 * 摄像头设置
 */
public class RTSPSet implements TextureView.SurfaceTextureListener, SurfaceHolder.Callback{

    private Context mContext;
    private Activity mActivity;
    private static final String TAG = "RTSPSet";

    private RTSPSet() {
    }

    private static RTSPSet _instance = null;

    public static RTSPSet getInstance() {
        if (_instance == null)
            _instance = new RTSPSet();
        return _instance;
    }

    /**
     * 播放区域
     */
    protected TextureView textureView;
    protected SurfaceTexture surfacetexture;
    protected ProgressBar progressBar;
    protected TextView playHintText;
    private int m_iPreviewHandle;
    private int m_iPlayBackID;
    private Handler mHandler;
    private boolean inThisView;

    public void setDataAndListen(Activity activity, Context context, View view) {
        inThisView = true;
        if (mContext == null) {
            mContext = context;
            mActivity = activity;

            m_iPreviewHandle = -1;
            m_iPlayBackID = -1;
            textureView = view.findViewById(R.id.texture_view);

            progressBar = view.findViewById(R.id.progress_bar);
            progressBar.setVisibility(View.VISIBLE);
            playHintText = view.findViewById(R.id.result_hint_text);
            playHintText.setVisibility(View.VISIBLE);
            playHintText.setTextColor(Color.RED);
            playHintText.setText("未连接摄像头，请右上角前往设置");

            textureView.setSurfaceTextureListener(this);

            view.findViewById(R.id.start).setOnClickListener(view1 -> startRealPlay());
            view.findViewById(R.id.stop).setOnClickListener(view1 -> stopRealPlay());
            /*view.findViewById(R.id.start_back).setOnClickListener(view1 -> startBackPlay());
            view.findViewById(R.id.stop_back).setOnClickListener(view1 -> stopBackPlay());*/
            view.findViewById(R.id.capture_button).setOnClickListener(view1 -> startSnap(Constant.realImageDir, System.currentTimeMillis()));
            view.findViewById(R.id.record_button).setOnClickListener(view1 -> startRecord());
            view.findViewById(R.id.stop_record_button).setOnClickListener(view1 -> stopRecord());

            View inflate = LayoutInflater.from(mContext).inflate(R.layout.rtsp_config, null);
            EditText rtspIp = inflate.findViewById(R.id.rtsp_ip);
            EditText rtspPort = inflate.findViewById(R.id.rtsp_port);
            EditText loginId = inflate.findViewById(R.id.login_id);
            EditText loginPassword = inflate.findViewById(R.id.login_password);

            rtspIp.setText((String) SharedPreferencesUtil.getInstance().getValue(Constant.rtspIp, Constant.rtspDefIp));
            rtspPort.setText((String) SharedPreferencesUtil.getInstance().getValue(Constant.rtspPort, Constant.rtspDefPort));
            loginId.setText((String) SharedPreferencesUtil.getInstance().getValue(Constant.rtspUser, Constant.rtspDefUser));
            loginPassword.setText((String) SharedPreferencesUtil.getInstance().getValue(Constant.rtspPassword, Constant.rtspDefPassword));


            view.findViewById(R.id.rtsp_set_bt).setOnClickListener(v -> {
                ViewGroup mViewGroup = (ViewGroup) inflate.getParent();
                if (mViewGroup != null && mViewGroup.getChildCount() > 0)
                    mViewGroup.removeView(inflate);
                new AlertDialog.Builder(mContext)
                        .setView(inflate)
                        .setPositiveButton("连接", (dialog, which) -> {

                            /*清除先前信息*/
                            SDKGuider.g_sdkGuider.m_comDMGuider.setCurrSelectDevIndex(-1);
                            SDKGuider.g_sdkGuider.m_comDMGuider.getDevList().clear();
                            progressBar.setVisibility(View.VISIBLE);

                            DevManageGuider.DeviceItem deviceItem = SDKGuider.g_sdkGuider.m_comDMGuider.new DeviceItem();
                            deviceItem.m_struNetInfo = SDKGuider.g_sdkGuider.m_comDMGuider.new DevNetInfo(
                                    rtspIp.getText().toString(),
                                    rtspPort.getText().toString(),
                                    loginId.getText().toString(),
                                    loginPassword.getText().toString());

                            if (SDKGuider.g_sdkGuider.m_comDMGuider.login_v40_jna("", deviceItem.m_struNetInfo)) {

                                SDKGuider.g_sdkGuider.m_comDMGuider.setCurrSelectDevIndex(SDKGuider.g_sdkGuider.m_comDMGuider.getDevList().size()-1);
                                if(SDKGuider.g_sdkGuider.m_comDMGuider.login_v40_jna_with_index(SDKGuider.g_sdkGuider.m_comDMGuider.getCurrSelectDevIndex())){
                                    dialog.dismiss();
                                    progressBar.setVisibility(View.GONE);
                                    playHintText.setTextColor(Color.GREEN);
                                    playHintText.setText("已连接到摄像头");
                                }else{
                                    int err = SDKGuider.g_sdkGuider.GetLastError_jni();
                                    playHintText.setTextColor(Color.RED);
                                    playHintText.setText(getErrorString(err));
                                }
                            } else {
                                int err = SDKGuider.g_sdkGuider.GetLastError_jni();
                                playHintText.setTextColor(Color.RED);
                                playHintText.setText(getErrorString(err));
                            }
                        })
                        .setNegativeButton("重置", (dialogInterface, i) -> {
                            rtspIp.setText(Constant.rtspDefIp);
                            rtspPort.setText(Constant.rtspDefPort);
                            loginId.setText(Constant.rtspDefUser);
                            loginPassword.setText(Constant.rtspDefPassword);
                            SharedPreferencesUtil.getInstance().putValue(Constant.rtspIp, Constant.rtspDefIp);
                            SharedPreferencesUtil.getInstance().putValue(Constant.rtspPort, Constant.rtspDefPort);
                            SharedPreferencesUtil.getInstance().putValue(Constant.rtspUser, Constant.rtspDefUser);
                            SharedPreferencesUtil.getInstance().putValue(Constant.rtspPassword, Constant.rtspDefPassword);
                        })
                        .show();
            });
        }
        mHandler = new Handler();
    }

    /*private void toast(int errorJni) {
        String mes;
        switch (errorJni){
            case 7:
                mes = ErrorCode.ERROR7.getMsg();
                break;
            case 1:
                mes = ErrorCode.ERROR1.getMsg();
                break;
            case 10086:
                mes = "连接成功";
                break;
            default:
                mes = "错误代码：" + errorJni;
                break;
        }
        ToastUtil.toast(mes);
    }*/

    private String getErrorString(int errorJni){
        String mes;
        switch (errorJni){
            case 7:
                mes = ErrorCode.ERROR7.getMsg();
                break;
            case 1:
                mes = ErrorCode.ERROR1.getMsg();
                break;
            case 10086:
                mes = "连接成功";
                break;
            default:
                mes = "错误代码：" + errorJni;
                break;
        }
        return mes;
    }

    /**
     * 开始预览
     */
    public void startRealPlay() {

        //Channel type
        DevManageGuider.DeviceItem deviceInfo = SDKGuider.g_sdkGuider.m_comDMGuider.getCurrSelectDev();
        if (deviceInfo == null) {
            showToast("未连接摄像头设备");
            return;
        }

        if(m_iPreviewHandle != -1){
            SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlay_Stop_jni(m_iPreviewHandle);
            m_iPreviewHandle = -1;
        }
        if (deviceInfo.m_lUserID < 0) {
            showToast("未连接摄像头设备");
            return;
        }

        NET_DVR_PREVIEWINFO_V20 struPlayInfo = new NET_DVR_PREVIEWINFO_V20();
        struPlayInfo.lChannel = 1;
        struPlayInfo.dwStreamType = 0;
        struPlayInfo.hHwnd = new Surface(surfacetexture);
        m_iPreviewHandle = SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlay_V40_jni(deviceInfo.m_lUserID, struPlayInfo, null);
        if (m_iPreviewHandle < 0) {
            int err = SDKGuider.g_sdkGuider.GetLastError_jni();
            //toast(err);
            if (inThisView){
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        playHintText.setTextColor(Color.RED);
                        playHintText.setText(getErrorString(err));
                    }
                });

            }
            return;
        }
        if (inThisView){
            mActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    playHintText.setVisibility(View.GONE);
                    textureView.setVisibility(View.VISIBLE);
                }
            });
        }
        Log.d("textureView","textureView:" + textureView.isAvailable() + "   m_iPreviewHandle:" + m_iPreviewHandle);
    }

    /**
     * 停止预览
     */
    public void stopRealPlay(){

        if(m_iPreviewHandle == -1){
            showToast("当前未有预览");
            return;
        }

        if (!SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlay_Stop_jni(m_iPreviewHandle)) {
            int err = SDKGuider.g_sdkGuider.GetLastError_jni();
            //toast(err);
            if (inThisView){
                playHintText.setTextColor(Color.RED);
                playHintText.setText(getErrorString(err));
            }
            return;
        }
        m_iPreviewHandle = -1;
        if (inThisView){
            mActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    playHintText.setVisibility(View.VISIBLE);
                    playHintText.setTextColor(Color.GREEN);
                    playHintText.setText("已连接到摄像头");
                    textureView.setVisibility(View.INVISIBLE);
                }
            });
        }
    }

    /**
     * 开始回放
     */
    private void startBackPlay(){

        DevManageGuider.DeviceItem deviceInfo = SDKGuider.g_sdkGuider.m_comDMGuider.getCurrSelectDev();
        if (deviceInfo == null) {
            ToastUtil.toast("未连接摄像头设备");
            return;
        }
        if(deviceInfo.m_lUserID != -1) {
            NET_DVR_TIME timeStart = new NET_DVR_TIME();
            NET_DVR_TIME timeStop = new NET_DVR_TIME();

            Calendar calStart = Calendar.getInstance();
            Calendar calEnd = Calendar.getInstance();
            calStart.setTime(getStartTime());
            calEnd.setTime(getEndTime());

            if(calEnd.compareTo(calStart) < 0) {
                ToastUtil.toast("The EndTime should larger than StartTime");
                return;
            }
            SDKGuider.g_sdkGuider.m_comPBGuider.ConvertToTime(timeStart,calStart);
            SDKGuider.g_sdkGuider.m_comPBGuider.ConvertToTime(timeStop,calEnd);

            NET_DVR_VOD_PARA vodParma = new NET_DVR_VOD_PARA();
            vodParma.struBeginTime = timeStart;
            vodParma.struEndTime = timeStop;
            vodParma.byStreamType = (byte) 0;
            vodParma.struIDInfo.dwChannel = 1;
            vodParma.hWnd = new Surface(surfacetexture);

            if(m_iPlayBackID != -1){
                ToastUtil.toast("maybe play back already,click stop button first m_iPlayBackID:" + m_iPlayBackID);
                return;
            }
            m_iPlayBackID = SDKGuider.g_sdkGuider.m_comPBGuider.PlayBackByTime_v40_jni(deviceInfo.m_lUserID,vodParma);
            if(m_iPlayBackID < 0){
                //toast(SDKGuider.g_sdkGuider.GetLastError_jni());
                return;
            }

            textureView.setVisibility(View.VISIBLE);
        }

    }
    /**
     * 停止回放
     */
    private void stopBackPlay(){
        if(m_iPlayBackID == -1){
            ToastUtil.toast("当前未有回放预览");
            return;
        }

        if (!SDKGuider.g_sdkGuider.m_comPBGuider.StopPlayBack_jni(m_iPlayBackID)) {
            //toast(SDKGuider.g_sdkGuider.GetLastError_jni());
            return;
        }
        m_iPlayBackID = -1;
        textureView.setVisibility(View.INVISIBLE);
    }

    /**
     *拍照
     */
    public boolean startSnap(String dirPath, long millis){
        if (m_iPreviewHandle < 0) {
            showToast("请先开始预览");
            return false;
        }
        if(!SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlay_Snap(m_iPreviewHandle, dirPath + millis + ".jpg")) {
            int err = SDKGuider.g_sdkGuider.GetLastError_jni();
            //toast(err);
            if (playHintText == null) return false;
            if (inThisView){
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        playHintText.setTextColor(Color.RED);
                        playHintText.setText(getErrorString(err));
                    }
                });

            }
            return false;
        }
        Log.d(TAG,"已拍摄照片，保存于:" + dirPath + millis + ".jpg");
        return true;
    }

    public boolean SnapPicture(String dirPath, long millis){
        startRealPlay();
        if (m_iPreviewHandle < 0) return false;
        if (!startSnap(dirPath, millis)) return false;

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                stopRealPlay();
            }
        }, 1500);

        return true;
    }

    public boolean RecordMovie(String dirPath, long millis){
        startRealPlay();
        if (m_iPreviewHandle < 0) return false;
        if (!startRecord()) return false;
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                stopRecord();
                stopRealPlay();
            }
        }, 10000);

        return true;
    }

    /**
     *开始录像
     */
    public boolean startRecord(){
        if (m_iPreviewHandle < 0) {
            ToastUtil.toast("请先开始预览");
            return false;
        }
        long millis = System.currentTimeMillis();
        if(!SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlay_Record(m_iPreviewHandle,1,  "/mnt/sdcard/Movies/" + millis + ".mp4")) {
            int err = SDKGuider.g_sdkGuider.GetLastError_jni();
            //toast(err);
            if (playHintText == null) return false;

            if (inThisView){
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        playHintText.setTextColor(Color.RED);
                        playHintText.setText(getErrorString(err));
                    }
                });

            }

            return false;
        }
        Log.d(TAG,"开始录像，保存于/mnt/sdcard/Movies/" + millis + ".mp4");
        return true;
    }

    /**
     *停止录像
     */
    public boolean stopRecord(){
        if (m_iPreviewHandle < 0) {
            showToast("请先开始预览");
            return false;
        }
        if(!SDKGuider.g_sdkGuider.m_comPreviewGuider.StopPlay_Record(m_iPreviewHandle)) {
            int err = SDKGuider.g_sdkGuider.GetLastError_jni();
            //toast(err);
            if (inThisView){
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        playHintText.setTextColor(Color.RED);
                        playHintText.setText(getErrorString(err));
                    }
                });

            }
            return false;
        }
        Log.d(TAG,"录像结束");
        return true;
    }

    private Date getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    private Date getEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        if (-1 == m_iPreviewHandle) {
            return;
        }
        Surface surface = surfaceHolder.getSurface();
        if (surface.isValid()) {
            if (-1 == SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlaySurfaceChanged_jni(m_iPreviewHandle, 0, surfaceHolder))
                Toast.makeText(mContext.getApplicationContext(),"NET_DVR_PlayBackSurfaceChanged"+ SDKGuider.g_sdkGuider.GetLastError_jni(),Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        if (-1 == m_iPreviewHandle) {
            return;
        }
        if (surfaceHolder.getSurface().isValid()) {
            if (-1 == SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlaySurfaceChanged_jni(m_iPreviewHandle, 0, null))
            {
                Toast.makeText(mContext.getApplicationContext(),"NET_DVR_RealPlaySurfaceChanged"+ SDKGuider.g_sdkGuider.GetLastError_jni(),Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
        surfacetexture = surfaceTexture;
        if (m_iPreviewHandle == 1){
            startRealPlay();
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        Log.d("007","surfaceDestroyed!!!");
        inThisView = false;
        stopRealPlay();
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

    }
    private final Handler handler=new Handler(Looper.getMainLooper());
    private void showToast(String message){
        if (mContext == null) {
            handler.post(() -> ToastUtil.create(WaterQualityApplication.getApplication().getApplicationContext(),message).show());
        } else {
            handler.post(() -> ToastUtil.create(mContext.getApplicationContext(),message).show());
        }
    }
}
